package com.xike.util;

import java.io.File;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import android.content.Context;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.provider.Settings.Secure;
import android.telephony.TelephonyManager;

import com.xike.net.ApacheClient;
import com.xike.net.HttpClient;
import com.xike.net.NetConstant;

public class Manager {

	private static Context context;

	public static Manager instance;
	/**
	 * 网络请求是否使用缓存
	 */
	public static boolean useNetCache = true;
	/**
	 * 当前网络是否需要使用代理
	 */
	public static boolean useProxy = false;
	/**
	 * 当前网络使用代理
	 */
	public static String netProxy = "";
	/**
	 * 当前网络类型
	 */
	private int netWork = NetConstant.NET_TYPE_UNKNOWN;

	/**
	 * 网络缓存的根目录
	 */
	public static String CACHE_HOME_PATH = "";

	/**
	 * 图片缓存的目录
	 */
	private static String CACHE_IMAGE_DIR = "/image/";
	/**
	 * apk缓存的目录
	 */
	private static String CACHE_APK_DIR = "/apk/";
	/**
	 * data缓存的目录
	 */
	private static String CACHE_DATA_DIR = "/data/";

	/**
	 * 线程池，用于网络异步请求。
	 */
	public static ExecutorService singleThread;

	public static SharedPreferences fileSp;
	public static SharedPreferences.Editor fileSpEditor;

	public static SharedPreferences appInfoSp;
	public static SharedPreferences.Editor appInfoSpEditor;

	public Manager(Context context, String cacheHomePath) {
		this.context = context;
		CACHE_HOME_PATH = cacheHomePath;
		init();
	}

	public Manager(Context context) {
		this.context = context;
		init();
	}

	public static Manager getInstance(Context context) {
		if (instance == null) {
			instance = new Manager(context);
		}
		return instance;
	}

	public static Manager getInstance(Context context, String cacheHomePath) {
		if (instance == null) {
			instance = new Manager(context, cacheHomePath);
		}
		return instance;
	}

	private void init() {
		MLog.e("init", "init");
		fileSp = context.getSharedPreferences(NetConstant.SHARED_PREFERENCES_FILECACHE, Context.MODE_PRIVATE);
		fileSpEditor = fileSp.edit();

		appInfoSp = context.getSharedPreferences(NetConstant.SHARED_PREFERENCES_APPINFOCACHE, Context.MODE_PRIVATE);
		appInfoSpEditor = appInfoSp.edit();

		singleThread = Executors.newFixedThreadPool(5);
		initCacheFile();
		checkNetWork();
		initHttpClient();
	}

	/**
	 * 
	 * @WZL wzl200711402@163.com @2012-12-6@上午09:10:07
	 * @description 初始化网络请求client
	 */
	private static HttpClient initHttpClient() {
		HttpClient client = new ApacheClient();

		// 设置head信息
		// client.setDefaultHeaders(new BasicHeader("uid", String.valueOf(NetConstant.VERSION.getVersionId())), new BasicHeader("pid", String.valueOf(NetConstant.VERSION.getPid())), new BasicHeader("ver", NetConstant.VERSION.getVer()), new BasicHeader("mid", String.valueOf(identify.getMid())), new BasicHeader("Did", identify.getDid()), new BasicHeader("sid", identify.getSid()), new BasicHeader("Key", StringUtil.MD5(identify.getDid() + Identify.KEYCODE)), new BasicHeader("tripledes", "100"));// 不加密

		// Log.e("ver", ""+NetConstant.VERSION.getVer());
		((ApacheClient) client).init(getCACHE_HOME_PATH());
		return client;
	}

	/**
	 * 
	 * @WZL wzl200711402@163.com @2012-7-27@下午01:45:19
	 * @description 检测当前网络状态
	 */
	private void checkNetWork() {
		ConnectivityManager ccm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo networkInfo = ccm.getActiveNetworkInfo();
		String apn = "";
		if (networkInfo != null) {
			netWork = networkInfo.getType();
			if (netWork == ConnectivityManager.TYPE_MOBILE) {
				apn = networkInfo.getExtraInfo().toLowerCase().trim();
				if (apn.startsWith("cmwap")) {
					netWork = NetConstant.NET_TYPE_CMWAP;
					useProxy = true;
					netProxy = NetConstant.PROXY_CMWAP;
				} else if (apn.startsWith("cmnet")) {
					netWork = NetConstant.NET_TYPE_CMNET;
				} else if (apn.startsWith("3gwap")) {
					netWork = NetConstant.NET_TYPE_3GWAP;
					useProxy = true;
					netProxy = NetConstant.PROXY_3GWAP;
				} else if (apn.startsWith("3gnet")) {
					netWork = NetConstant.NET_TYPE_3GNET;
				} else if (apn.startsWith("ctwap")) {
					netWork = NetConstant.NET_TYPE_CTWAP;
					// Manager.useProxy = true;
					// Manager.netProxy = Constant.PROXY_CTWAP;
				} else if (apn.startsWith("ctnet")) {
					netWork = NetConstant.NET_TYPE_CTNET;
				} else {
					netWork = NetConstant.NET_TYPE_MOBILE;
				}
			}
		}

	}

	/**
	 * 
	 * @WZL wzl200711402@163.com @2012-7-27@下午02:03:05
	 * @description 初始化文件缓存文件夹
	 */
	private void initCacheFile() {
		String cacheHomePath = getCACHE_HOME_PATH();
		MLog.e("initCacheFile", "cacheHomePath:" + cacheHomePath);
		File cacheHomeFileDir = new File(cacheHomePath);
		if (!cacheHomeFileDir.exists()) {
			if (!cacheHomeFileDir.mkdir()) {
				MLog.e("initCacheFile", "error!");
				useNetCache = false;
				return;
			} else {
				cacheHomeFileDir.mkdirs();
			}
		}

		String cacheImagePath = getCACHE_IMAGE_DIR();
		File cacheImageFileDir = new File(cacheImagePath);
		if (!cacheImageFileDir.exists()) {
			cacheImageFileDir.mkdirs();
		}
		String cacheApkPath = getCACHE_APK_DIR();
		File cacheApkFileDir = new File(cacheApkPath);
		if (!cacheApkFileDir.exists()) {
			cacheApkFileDir.mkdirs();
		}
		String cacheDataFilePath = getCACHE_DATA_DIR();
		File cacheDataFileDir = new File(cacheDataFilePath);
		if (!cacheDataFileDir.exists()) {
			cacheDataFileDir.mkdirs();
		}
		MLog.e("initCacheFile", "ok!");
		deleteExpiredFileCache();
	}

	/**
	 * @description:TODO删除文件缓存文件夹
	 * @FileName Manager.java
	 * @params
	 * @return void
	 * @user wzl email:wzl200711402@163.com
	 * @date 2013-5-27
	 */
	public static boolean deleteFileCache() {
		try {
			File homeFile = new File(getCACHE_HOME_PATH());
			File cacheImageFile = new File(getCACHE_IMAGE_DIR());
			File cacheDataFile = new File(getCACHE_DATA_DIR());
			if (homeFile.exists()) {
				for (File file : homeFile.listFiles()) {
					if (file.isFile()) {
						file.delete();// 清空
					}
				}
			}
			if (cacheImageFile.exists()) {
				for (File file : cacheImageFile.listFiles()) {
					file.delete();// 清空
				}
			}
			if (cacheDataFile.exists()) {
				for (File file : cacheDataFile.listFiles()) {
					file.delete();// 清空
				}
			}
			MLog.e("Manager", "clear cache");
			fileSpEditor.clear();
			fileSpEditor.commit();
			System.gc();
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	public static String getCACHE_HOME_PATH() {
		if (null == CACHE_HOME_PATH || CACHE_HOME_PATH.equals("")) {

			String strPackageName = context.getPackageName();
			if (strPackageName.contains(".")) {
				strPackageName = strPackageName.substring(strPackageName.lastIndexOf(".") + 1);
			}

			if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED) && checkAvailableStorage()) {
				// TODO 区分手机与机顶盒。手机根目录为sdcard，盒子也许不是这个名称
				CACHE_HOME_PATH = Environment.getExternalStorageDirectory().getPath() + File.separator + strPackageName; // 如果SD卡可用，默认缓存文件夹为sdcard下的应用名称
			} else { // SD卡不可用
				if (new File("data/data").canRead()) {// 如果data/data/可读，默认缓存文件夹为data/data/com.m1905.tv/cache
					CACHE_HOME_PATH = context.getCacheDir().getAbsolutePath() + "/";
				} else if (new File("system/app").canRead()) {// 否则判断system是否可读，设置默认缓存文件夹
					CACHE_HOME_PATH = "system/app/" + strPackageName;
				}
			}
		}
		return CACHE_HOME_PATH;
	}

	public static boolean isUseProxy() {
		return useProxy;
	}

	public static String getNetProxy() {
		return netProxy;
	}

	public int getNetWork() {
		return netWork;
	}

	public void setNetWork(int netWork) {
		this.netWork = netWork;
	}

	/**
	 * 删除缓存文件 如果文件时间超过10天(864000000毫秒)则删除
	 */
	private void deleteExpiredFileCache() {
		long current = System.currentTimeMillis();
		File cacheDir = new File(getCACHE_HOME_PATH());
		if (cacheDir.exists() && cacheDir.isDirectory()) {
			File[] caches = cacheDir.listFiles();
			for (File f : caches) {
				if ((current - f.lastModified()) > 864000000L) {
					f.delete();
				}
			}
		}
	}

	/**
	 * @return
	 * @WZL wzl200711402@163.com @2013-1-6@上午11:16:09
	 * @description 获得图片的缓存根目录
	 */
	public static String getCACHE_IMAGE_DIR() {
		return getCACHE_HOME_PATH() + CACHE_IMAGE_DIR;
	}

	public static String getCACHE_IMAGE_RELATIVE_PATH() {
		String strPackageName = context.getPackageName();
		if (strPackageName.contains(".")) {
			strPackageName = strPackageName.substring(strPackageName.lastIndexOf(".") + 1);
		}
		return strPackageName + File.separator + CACHE_IMAGE_DIR;
	}

	/**
	 * @return
	 * @WZL wzl200711402@163.com @2013-1-6@上午11:16:09
	 * @description 获得Apk的缓存根目录
	 */
	public static String getCACHE_APK_DIR() {
		return getCACHE_HOME_PATH() + CACHE_APK_DIR;
	}

	/**
	 * @description:TODO获得file的缓存根目录
	 * @FileName NetManager.java
	 * @params @return
	 * @return String
	 * @user wzl email:wzl200711402@163.com
	 * @date 2013-4-11
	 */
	public static String getCACHE_DATA_DIR() {
		return getCACHE_HOME_PATH() + CACHE_DATA_DIR;
	}

	public static HttpClient getClient() {
		return initHttpClient();
	}

	public void shutDown() {

		if (null != singleThread && !singleThread.isShutdown()) {
			singleThread.shutdown();
		}

		instance = null;
	}

	private static final long LOW_STORAGE_THRESHOLD = 1024 * 1024 * 5;

	/**
	 * @return
	 * @WZL wzl200711402@163.com @2013-1-6@上午11:09:43
	 * @description 获得sdcard剩余容量
	 */
	public static long getAvailableStorage() {
		String storageDirectory = null;
		storageDirectory = Environment.getExternalStorageDirectory().toString();
		long avaliableSize;
		try {
			StatFs stat = new StatFs(storageDirectory);
			avaliableSize = ((long) stat.getAvailableBlocks() * (long) stat.getBlockSize());
			return avaliableSize;
		} catch (RuntimeException ex) {
			// if we can't stat the filesystem then we don't know how many
			// free bytes exist. It might be zero but just leave it
			// blank since we really don't know.
			return 0;
		}
	}

	/**
	 * @return
	 * @WZL wzl200711402@163.com @2013-1-6@上午11:10:13
	 * @description sdcard 剩余容量是否可用
	 */
	public static boolean checkAvailableStorage() {
		if (getAvailableStorage() < LOW_STORAGE_THRESHOLD) {
			MLog.e("checkAvailableStorage", "no available storage");
			return false;
		}
		return true;
	}

	/**
	 * @return 设备唯一标示
	 */
	public static String getClientInfo() {
		StringBuffer sb = new StringBuffer();
		try {
			TelephonyManager TelephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
			String m_szImei = TelephonyMgr.getDeviceId();
			sb.append(m_szImei);

			String m_szDevIDShort = "35" + Build.BOARD.length() % 10 + Build.BRAND.length() % 10 + Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 + Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 + Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 + Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 + Build.TAGS.length() % 10 + Build.TYPE.length() % 10 + Build.USER.length() % 10; // 13
			sb.append(m_szDevIDShort);

			String m_szAndroidID = Secure.getString(context.getContentResolver(), Secure.ANDROID_ID);
			sb.append(m_szAndroidID);

			WifiManager wm = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
			String m_szWLANMAC = wm.getConnectionInfo().getMacAddress();
			sb.append(m_szWLANMAC);

			// BluetoothAdapter m_BluetoothAdapter = null; // Local Bluetooth
			// m_BluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
			// String m_szBTMAC = m_BluetoothAdapter.getAddress();
			// sb.append(m_szBTMAC);

		} catch (Exception e) {
			e.printStackTrace();
		}

		return StringUtil.MD5(sb.toString());
	}
}
